perm filename 20MAN.TXT[SCH,LSP]1 blob sn#688814 filedate 1982-11-14 generic text, type T, neo UTF8
                A 6.001 User's Guide to the DECsystem-20

                   Originally by Kevin B. Theobald
            First draft started 3/17/80, completed 4/22/80
	    Revisions:	KMP, GJS, SK    8/80
			HAL		1/81
			BOWB		8/81
                        SHOMIE		8/82

	This manual is a brief introduction to the TOPS-20 operating
system, intended primarily for use by students in 6.001. The manual is
divided into three main sections. The first section outlines the
general procedure for writing, editing and running SCHEME programs on
the DECsystem 20, then introduces the TOPS-20 operating system and its
role in this procedure. The second section is a simple introduction to
the EMACS text editor. The third section is a brief introduction to
SCHEME, the particular LISP interpreter which will be used in 6.001.
The manual is geared toward students who may have had prior computer
experience, but are unfamiliar with the systems presented here.

	When first learning to use these systems, the beginner should
first scan this manual to gain an overall view of how the system
works, then read the manual thoroughly while sitting at a terminal.
This manual is designed for this method of learning, so there are many
examples showing sample computer input and output.

	The following symbols, conventions and terms are used
throughout this manual:


    Symbol	Description
    or Type

	↑	This represents the CTRL (CONTROL) key.  The symbol means
		that the CTRL key should be held down while the
		character immediately following the "↑" symbol is
		typed.  This rule only applies to the first character
		following the "↑".  For example, "↑XS" represents a "↑X"
		followed by an ordinary "S". Characters generated while
		the CTRL key is depressed are called control
		characters.

		If the computer prints a control character, it will
		preceed the letter with the "↑" symbol.

		Note that there is a "↑" character on the keyboard.
		Typing this character does not have the same effect as
		the CTRL key.

	{⎇	Braces indicate that the phrase between them is not a
		string of characters to be typed in literally, but
		rather a general term for a variable object. For
		example, the form

			delete {filename⎇

		means that you should type in "delete" followed by a
		space and the name of your file.

	{cr⎇	Indicates that the RETURN (carriage return) key, usually
		located in the lower-right corner of the keyboard,
		should be typed. TOPS-20 commands are generally
		terminated with a {cr⎇, although this is not true in
		EMACS.

	{esc⎇	Indicates that the ESC key (ESCAPE; ALT or ALTMODE on
		some terminals), located in the upper-left corner of
		the keyboard, should be typed.  When the computer echos
		the ESC character (i.e., if it prints it on the screen
		when you type it), it uses a dollar sign ("$") to
		designate the ESC. Like the CTRL key and "↑", the ESC key is
		not the same as the "$" key.

	{del⎇	Indicates that the DEL key (DELETE; RUB or RUBOUT on
		some terminals), should be typed. When typing {del⎇
                will delete the last character typed.

	{space⎇	Indicates that a space should be typed.

	upper-	None of the systems described in this manual
	case	distinguish between upper- and lower-case letters, so
		unless the user is typing English text, everything can
		be typed using lower-case letters. In this manual,
		upper-case letters are used to indicate computer
		output. For example, the form

			login{esc⎇ (USER)

		indicates that the user types login{esc⎇ and the
		computer responds with (USER).

		The only exceptions to this rule are the control
		characters. Control characters do not distinguish
		between upper- and lower-case letters, so they are
		conventionally represented by upper-case letters.

	cursor	The cursor is usually a blinking square on the terminal
		screen.  It sometimes masquerades as an underscore and
		sometimes does not like to blink.  The cursor indicates
		where the next character typed will be inserted.

1. INTRODUCTION TO TOPS-20



	The general procedure for using SCHEME on the TOPS-20 system is
as follows:


	1) Log into the TOPS-20 operating system.

	2) Invoke the SCHEME interpreter by typing SCHEME{cr⎇ at the
	   EXEC level of the TOPS-20 system.

	3) If you already have a program that you want to work on stored
	   in a TOPS-20 file, load it into SCHEME using the LOAD procedure
	   as described later.  If not, go to step 6.

	4) Test your program.

	5) If you are satisfied with your program, return to TOPS-20 using
	   (QUIT) and log out.  If not, you must edit your work.

	6) Use the EDIT command of SCHEME to enter EMACS so that you can
	   make a program file or edit your existing file.  You will need
	   to visit your file (see the EMACS command ↑X↑V) with EMACS the
	   first time you use the EDIT command in SCHEME, but from then on
	   your file will remain in EMACS.

	7) Make the necessary corrections to your file, then return to
	   SCHEME for testing it (step 4).  You may have to mark the regions
	   of the file which you have changed so that the updated version is 
	   transmitted back to SCHEME when you return to SCHEME.  See the 
	   description of the EDIT command in the SCHEME manual for an 
	   explanation of how this is done.

	SCHEME is accessed via the TOPS-20 operating system, but the
TOPS-20 system also has commands which allow you to perform "housekeeping"
functions with your files, such as listing them and getting rid of those
that are old and unneeded.



1.1 LOGGING IN AND OUT

	To use TOPS-20, EMACS and SCHEME, you must first get into EXEC,
the part of TOPS-20 that interprets the commands you give. Then you must
log into your account.

First, find a free terminal. You should see a message like

	Welcome to MIT-EECS.

at the top of the screen. If the terminal is already on, you should see
either the above message or one like

	LOGOUT JOB 11, USER 001.THEOBALD, ACCOUNT 6001, TTY 6,
	  AT 20-MAR-82 19:21:54,  USED 0:1:30 IN 0:50:20

If you don't see such a message, then the last user may have forgotten
to log out.  Ask a neighbor or a Teaching Assistant if the terminal is
really free.  If you determine it is (be careful because you may be
destroying someone's work), type ↑C, then type

        logout

(Terminate this command and all others in this section with {cr⎇ unless
otherwise noted.)

	To get the system's attention, type ↑C. The system should
respond with a short message identifying itself, then print a '@'
character. This character is a prompt, which means that EXEC, the
command interpreter, is waiting for you to type something.

The format for logging in is

		login {username⎇ {password⎇

Note that the three words are separated by spaces. Your {username⎇ is
the name of your account, and it distinguishes your accounts from
others.  Your {password⎇ is an access word which only you know. The
password prevents others from using your account. In an effort to keep
your password secret, the terminal doesn't echo (display your input on
the terminal) when you type your password. Therefore, if your username
is ls.theobald, the terminal will display

		@login ls.theobald

If you receive a message like

		?DOES NOT MATCH DIRECTORY OR USER NAME

then you didn't type the username properly. Similarly, the message

		?INCORRECT PASSWORD

means you typed the password incorrectly. Try logging in again.

	When you are finished using the terminal, return to EXEC (with a
↑C) and type

		logout


1.2 SPECIAL TOPS-20 CHARACTERS



	There are several special characters you can use to correct
typing mistakes and invoke special TOPS-20 functions. These characters,
unlike most commands in this section, are not followed by a {cr⎇.


    Character	Description

	{del⎇	This deletes the last character typed. For example,

			la{del⎇ogiu{del⎇{del⎇out

		is equivalent to "logout". A video terminal will move
		the cursor backwards and remove the mistake. A printer
		will reprint the mistake and follow it with a slash,
		but the mistake is still removed from EXEC's memory.

	↑U	This deletes the entire line just typed.

	↑L	This clears the screen and redisplays the current line.
		You can still rubout the characters on this redisplayed line.

	↑Q	This is used only if your terminal is in "page" mode
		(see sec. 1.5). If the terminal has printed a page and
		has stopped, ↑Q will start the printing again. This is
		explained in further detail in sec. 1.5.

    {esc⎇	If this is typed while at the EXEC command level
		and at certain times in EMACS, it will invoke a
		feature called "recognition input". When {esc⎇ is
		typed, EXEC will attempt to complete a command
		field if it is incomplete. A field is a part of the
		command which is separated from the other parts by
		spaces or other punctuation marks. For example, the
		login command has three fields: "login", the
		username and the password. The partially-completed
		command field must have enough letters to make it
		indistinguishable from the other possible commands
		(see "?" below), otherwise, typing {esc⎇ will do
		nothing but make the terminal "beep". For example,
		lo{esc⎇ will not work, since there are commands
		called load, login and logout.

		The {esc⎇ command will not complete your password, for
		obvious reasons, although it will complete your
		username.

		When the computer completes the command field, it will
		also print a phrase indicating what should go in the
		following command field. For example, if you type

			log{esc⎇

		the computer will complete the field and ask for the
		next field:

			logIN (USER)

		(Even though both "login" and "logout" begin with
		"log", you only need to type "log" to log in, since
		EXEC knows that you are trying to log in. However, you
		must type "logo" to log out.)

		Once the entire command has been completed, a {cr⎇ will
		tell EXEC to execute it.

		Note: you do not need to use the {esc⎇ function to
		complete a command field. To type a command, you only
		need to type enough letters to distinguish it from all
		other commands. For example, you only need to type
		"di" to use the "directory" command. Once you are
		familiar with the commands, you may use this
		time-saving feature.  However, the {esc⎇ key MUST be
		pressed to complete filenames.  The characters and fields
		of the partially/fully completed filename may be
		edited with {del⎇, ↑W, and  ↑U as usual.

	↑W	This deletes the command field currently being typed.
		For example, if you type

			login lt

		followed by a ↑W, EXEC will delete the "lt"; you may
		then type in another username.

	↑?	This is a call for help, and it can be used in many
		ways.  (Note:  just plain ? works, too.)

		Typing ? after a @ prompt will produce a list of all
		EXEC commands.

		Typing ? instead of a command field will produce a
		list of all the options you can choose to put in
		the command field.

		If {esc⎇ does not complete an incomplete field
		because the field doesn't have a unique completion,
		"?" will produce a list of those commands or fields
		which start with your field. For example, if you type

			lo{esc⎇

		the terminal will "beep", because EXEC cannot uniquely
		complete this command. If you then type "?", EXEC will
		respond with

			lo? COMMAND, ONE OF THE FOLLOWING:
			LOAD   LOGIN   LOGOUT
			@LO

		Note that your input line is retyped, so you may
		complete the command as if you had just typed in
		the first two characters.



1.3 RUNNING PROGRAMS

	There are two kinds of input that TOPS-20 will accept: commands
and program names. Commands, such as login and logout, are routines
executed by EXEC. Programs are routines which exist on a lower level,
hence, they are not executed by EXEC, but are only accessed by it.

	EMACS and SCHEME are programs.	To invoke a program, type its
name to EXEC.  Thus, typing "SCHEME" or "SCH"{esc⎇ will invoke SCHEME,
our LISP interpreter.  The mechanism TOPS-20 uses to keep track of
these programs is called a "fork."  Each program you start creates a
new fork.

	When you have finished using a program, you can get back to
EXEC by typing ↑C↑C. (Actually, only one ↑C is needed if the program
is awaiting input, but two ↑Cs will always work and the extra ↑C will
not harm anything.) If you exit a SCHEME or EMACS in this manner, you
will not terminate it; it will only be suspended. The fork you created
will remain and may be reactivated.  (Actually, this is only true for
programs, such as SCHEME, which have been set to "autokeep".  Exiting
other programs via ↑C may terminate them.)

	To reactivate a suspended program, type its name again. Your
program will continue where it left off when you suspended it.  Do not
use the {esc⎇ key to complete the name of a suspended program.  For
some obscure reason, this will create a new fork rather than resume
the old fork.

	If you follow the steps given at the beginning of sec. 1 for
using SCHEME, your session will look something like this:

		@login ls.theobald
		 JOB 17 ON TTY6 24-MAR-82 20:26
		 PREVIOUS LOGIN: 21-MAR-82 18:42
		@SCHEME
		[KEEPING]
		    .
		    .     {use of SCHEME⎇
		    .
		==> (edit)
		(=> EMACS)
		    .
		    .     {use of EMACS⎇
		    .
		↑XZ
		(SCHEME <=)
		    .
		    .     {continuing use of SCHEME⎇
		    .
		==> (edit)
		    .
		    .     {repeat until SCHEME program works⎇
		    .
		==> (quit)

	Now you know the essentials -- how to start, stop, and restart
programs.  Some of the fine points are revealed below.  Skip to the
next section if this sort of thing doesn't appeal to you.

At EXEC level you can obtain information about the forks you are using
by typing

	information fork-status

which can be abbreviated "in fo".  You will see something like

	 => SCHEME (1): ↑C FROM IO WAIT AT 116710, 0:03:34.7
	    EMACS (2): HALT at 41301, 0:01:01.9

TOPS-20 assigns each fork a number, in the order that they are
created.  The arrow by SCHEME indicates that SCHEME is the "current"
fork, i.e., the fork used most recently.

If you are no longer using a fork, you can remove it by typing

	reset {fork⎇

where {fork⎇ can be either the name or the number assigned to it. If
no argument is given for {fork⎇, then EXEC will remove all unkept
forks (see below). If the current fork is removed, the
highest-numbered fork becomes the current fork.  If you reset a fork,
EXEC will always print the name of the current fork (the new current
fork if you reset the old current fork) in brackets.

If you type

		keep {fork⎇

the specified fork (or the current fork if none is specified) will be
"kept".  If the current fork is "kept", you cannot remove it with the
reset command unless you also specify the name or number. This is to
prevent you from accidently removing wanted programs.  SCHEME
automatically "keeps" itself when it is called.  Thus to remove it,
one needs to type

	reset scheme

or

	reset {scheme's fork-number⎇

to remove it.

1.4 TOPS-20 FILES

	When you write files they are stored in a directory assigned
to your account.  A directory is a block of memory with a certain size
limitation, which will quickly be exceeded if you leave old, unneeded
files in your directory.  This section and the next describe the basic
"housekeeping" functions of TOPS-20, including those that allow you to
remove old files, print and copy files, and list your directory.

	Each file must have a filename to distinguish it from other
files. The basic format for a filename is

	{device⎇:<{username⎇>{name1⎇.{name2⎇.{generation number⎇

	The device is the name of the main memory structure in which your
directory is located, and the name of the device is always followed by a
colon.  The username is the name of your account. It is enclosed in
angle-brackets. If the first two fields are not specified, then your
device and username are used as default values. Since you will usually be
working with files in your own directory, the only part you need to worry
about is the last part:

		{name1⎇.{name2⎇.{generation number⎇

	{name1⎇ is a word that describes what is in the file.  It can be,
for example, the name of a SCHEME procedure or a word describing its purpose
or contents.  Name2 is another word, but some programs require it be set
to a particular string.  For example, the SCHEME interpreter requires you
to use "SCM" to show that the file contains a SCHEME program.  Other
standard types include ALG for ALGOL and TXT for text.  For this reason,
Name2 is often referred to as the "type" of the file.  Up to 32
characters are permitted for the "name" part of the filename (Name1 and
Name2).

	Generation numbers are positive integers used to specify the
revision number of the file.  Generally, the first draft of a file is
generation number 1, the first revision is number 2, etc. There is a
special feature that allows you to dispense with generation numbers

altogether. If you do not specify a generation number when you deal with
a file, the system will assign one based on the following rules:

	1) If the command reads the file, then EXEC looks through all
	   files which match the name and type specified in the
	   command, and chooses the one with the highest generation
	   number. If no file in your directory matches the specified
	   file name and type, an error message is returned.

	2) If the command writes the file, then it creates a new file.
	   The generation number of this file is 1 greater than the
	   highest existing generation number. If no file in your
	   directory matches the specified name and type, the new file
	   is given the generation number 1.

	3) Some EXEC commands will act on all files in your directory
	   matching the specified name and type. These commands will be
	   described in sec. 1.6.


	For example, suppose your directory is empty. If you create a
program in EMACS, use the appropriate EMACS command (see sec. 2) to write
it into a file, and you only specify

		program.scm

as the file name, your directory will now contain the file program.scm.1.
If you perform another write function, your directory will contain
program.scm.1 and program.scm.2. If you read a file, and you don't
specify a generation number, the file program.scm.2 will be read.

	If you consistently use this feature, you will always read the
most recent revision of your file, and always write revisions into new
files. This is almost always the right thing to do.  You may then ignore
the generation numbers unless you need to recover an old version of a
program.  Note that only the three most recent generations are kept in
your directory.  Older generations are automatically expunged.

1.5 EXEC COMMANDS

	The following section contains a summary of useful "housekeeping"
commands. To execute a command, simply type its name. No additional
fields are needed unless otherwise specified. The ? and {esc⎇ functions

will help you if you aren't sure if additional fields are necessary.


1.5.1  FILE COMMANDS

DIRECTORY

	This command gives a short listing of the files in your
directory. If a file has more than one generation number, all the
generation numbers are printed on one line, separated by commas. If a
file has more than one type, the additional type names and their
corresponding generation numbers are identified and printed below the
main file name. For example, the directory listing

		  PS:<LS.THEOBALD>
		PROGRAM.SCM.1,2
		  .BAS.3

indicates that the directory of account ls.THEOBALD, on device PS, has
the files PROGRAM.SCM.1, PROGRAM.SCM.2, and PROGRAM.BAS.3.

	The commands tdirectory, wdirectory and rdirectory will tell you
when your files were written, who wrote them, and how long they are,
repectively.  The command fdirectory gives all this information in one
listing.


TYPE

	The command

		type {filename 1⎇, {filename 2⎇, ... {filename n⎇

will type all the files specified on the terminal. If you specify only
one file, no comma is necessary.

PRINT

	This command is identical to the type command, except that the
output is sent to the lineprinter instead of the terminal. This is useful
if you are using a video terminal and you want a hardcopy (paper) listing
of your file.  After executing this command, you may type other commands
as soon as the prompt reappears, even if the printer hasn't finished
printing your file.  If you decide to cancel your listing, type "i out"
and note the request number.  Then type "cancel print {number⎇" to cancel
the print request.  You will only be able to cancel your own print requests.


DELETE, UNDELETE

The command

	delete {filename 1⎇, {filename 2⎇, ... {filename n⎇

will remove all the specified files from your directory. Any directory
listings taken afterward will not list {filename⎇. However, these files
still reside in memory until they are expunged or you log out.  They can
be returned to your directory by typing

	undelete {filename 1⎇, {filename 2⎇, ... {filename n⎇

If the generation number is not specified, delete and undelete will
affect all generations with the same name and type.


EXPUNGE

	Even though deleted files don't appear in your directory, they
still reside in memory. You will quickly fill your alloted space in
memory if you don't occasionally eliminate old deleted files. The expunge
command, which does not take arguments, will permanently flush all deleted
files from memory. Once a file has been expunged, it can't be restored, so
you should always list your directory before expunging to make sure you
haven't deleted anything you want to keep.  Your directory is automatically 
expunged when you log out.


COPY

The command

	copy {filename 1⎇ {filename 2⎇

copies the contents of {filename 1⎇ into {filename 2⎇; {filename 1⎇
remains intact. The copy command reads {filename 1⎇ and writes onto
{filename 2⎇, so if no generation numbers are specified, the command
follows the rules for assigning them, as described in sec. 1.4.
RENAME

The command

	rename {filename 1⎇ {filename 2⎇

changes the name of {filename 1⎇ to {filename 2⎇. If generation numbers
are not specified, then they are assigned according to the rules
described in sec. 1.4.



1.5.2  MISCELLANEOUS EXEC COMMANDS


HELP

Typing

	help {program name⎇

will describe the program {program name⎇ in detail. Typing ? in place of
{program name⎇ will print a list of the programs for which help is
available.  The system's mail handler, MM, is one program that you might
need help with.


INFORMATION

	This command will provide information about your use of the
system. The second field specifies the type of information wanted. For
example,

	information disk-usage

gives information about the directory and the amount of memory it is
currently using.

	information fork

lists the forks that are in use. (See sec. 1.3.)

	information terminal

lists information about the terminal, such as the type of terminal and
the page dimensions.

	information ?

will list all the options available.

MM

	Electronic mailbox.  This is actually a program and not a command.
Using MM, you can send mail to your fellow students and teachers, and read
mail which has been sent to you.  Documentation is available via EXEC's
HELP command.


SET DIRECTORY PASSWORD

	This command is used to change the password of your account. The
format (including computer output) is

	set directory password <{username⎇>{cr⎇
	OLD PASSWORD: {old password⎇{cr⎇
	NEW PASSWORD: {new password⎇{cr⎇
	RETYPE NEW PASSWORD: {new password⎇{cr⎇

The passwords are not echoed by the computer.


TERMINAL

	This command has several options that allow you to change some of
the terminal's characteristics. For example,

	terminal width {width⎇

({width⎇ a positive integer) will change the line width to {width⎇
characters.

	terminal page

will change your terminal to page mode. If you use the type command to
print a long file, the printing will stop after a page has been printed.
To resume the printing, type ↑Q.

	terminal length {length⎇

({length⎇ a positive integer) will change the page length to {length⎇
lines.

	TOPS-20 has correct default values for parameters such as the
width and length. Therefore, you generally will not need to change any
parameters, unless someone has previously tampered with them.


XINFO

	This program (not a command) puts a wealth of information
about the TOPS-20 system at your finger tips.  Type an "H" if you wish
to take the time required to learn how to use it.

2. INTRODUCTION TO EMACS

	EMACS is the text editor which allows you to write, edit and
correct your files.  It is a real-time editor, which means that any
changes you make in your file are immediately displayed on the terminal
screen. This section describes how to write and modify files using EMACS.

	If you have the time, you may find it easier to learn EMACS
on-line.  Run the TEACH-EMACS ("tea{esc⎇") program and follow the
instructions it types at you.  Caution: TEACH-EMACS presumes that you
are using EMACS as a top-level fork on the system rather than as a
subfork of another system (SCHEME).  Thus TEACH-EMACS tells you about
entering and exiting EMACS in a way relevant to that usage, not our
usage.  Please remember not to use EMACS this way when you are editing
SCHEME programs accessed by the SCHEME (EDIT) command.


2.1 BUFFER STORAGE

	When editing, your file is held in a buffer.  All commands
affect the buffer, but not your file.  To make your changes perma-
nent, you have to write the buffer to the file.  More details below.

2.1.1 THE BUFFER POINTER

	You can add text to the buffer by typing it in. As you type, the
screen will be updated continually. It is this feature that makes EMACS a
real-time editor.

	EMACS uses a "buffer pointer" to mark the point in the buffer it
is working on.  The buffer pointer is represented on the screen by the
cursor. The cursor always points to a character or space on the screen,
but the buffer pointer is actually between the cursor and the previous
character. The character at the cursor is "to the right" of the pointer,
while the previous character is "to the left". If you type in text, the
pointer will always be to the right of the last character typed.

	When you first invoke EMACS, there is nothing in the buffer, so
the pointer is in the upper-left corner. If you now type

(define (fact n)

(with no {cr⎇) the screen will look like this:

(define (fact n)←

(The underline represents the cursor.) If you now type {cr⎇, the screen
will look like this:

(define (fact n)
←

EMACS has moved the pointer to the beginning of the next line. EMACS has
marked the end of the first line with a {cr⎇, although the terminal
doesn't show it.  If you type ↑B, the EMACS command to move the buffer
pointer back a character, the pointer will move back to the end of the
first line.

	If the {cr⎇ character is deleted, the following line will be
added to the end of the first line. For example, if the screen displays

(define (fact n)←
       (cond ((zero? n) 1)

and you type ↑D, the command to delete the character pointed to by the
pointer, the screen will now display:

(define (fact n)←      (cond ((zero? n) 1)

2.2 EMACS COMMANDS

	Due to space limitations, we only describe a few of the thousands
of EMACS commands available.  We have listed most commands you will ever
need to use, but you can get by with fewer commands if you feel
uncomfortable with such a large selection.  The choice is yours.

	As a general rule, control character commands deal with
characters, {esc⎇ commands deal with words and sentences, and ↑Z commands
deal with SCHEME symbolic expressions (S-expressions).


2.2.1 POINTER-DEPENDENT COMMANDS

	The following commands are pointer-dependent; they operate on
characters near the buffer pointer. These commands, and all others given
in section 2, are not terminated with a {cr⎇ unless otherwise noted.


Type of	     Command	Description
command

MOVING THE	↑F	Move the pointer forward one character.
BUFFER
POINTER		↑B	Move the pointer backward one character.
		or ↑H

		↑A	Move the pointer to the beginning of the line.

		↑E	Move the pointer to the end of the line.

		↑N	Move the pointer to the next line.

		↑P	Move the pointer to the previous line.

		{esc⎇<	Moves the pointer to the beginning of the buffer.

		{esc⎇>	Moves the pointer to the end of the buffer.

		{esc⎇F	Move the pointer forward until it reaches the
			end of a word.

		{esc⎇B	Move the pointer back until it reaches the
			beginning of a word.

		{esc⎇A  Move the pointer to beginning of sentence.

		{esc⎇E	Move the pointer to the end of sentence.

		↑Z↑F	Moves the pointer forward an s-expression.

		↑Z↑B	Moves the pointer backward an s-expression.

		↑Z↑A	Move the pointer back until it either reaches
			the beginning of the buffer or the beginning
			of a DEFINE. EMACS defines a DEFINE as a line
			that begins with a "(". If the "(" is indented
			(preceded by spaces or tabs), the line is not
			a DEFINE.  In most cases, an EMACS DEFINE will be
			a SCHEME procedure DEFINEition.

		↑Z↑E	Move the pointer forward until it passes the
			end of a DEFINE. The end of a DEFINE is the {cr⎇
			to the right of the closing delimiter (right
			parenthesis, bracket or brace) that
			corresponds to the beginning of a DEFINE. This
			command should only be used when editing SCHEME
			files, since typing ↑Z↑E when there are no
			DEFINEs will result in an error message.

			For example, suppose the buffer contains the
			DEFINE

				(define (print-x x)
				       (print x))

			and the pointer is at the end of the first
			line. Typing ↑Z↑A will move the pointer to the
			beginning of the first line, while ↑Z↑E will
			move the pointer to the beginning of the third
			line.

		↑S	This command puts EMACS into an incremental search 
			mode. The format for a search is ↑S{string⎇. As you
			type {string⎇, EMACS moves the pointer forward until it
			reaches the end of an occurrence of the accumulated
			string. The pointer is moved to the right of the first
			occurrence. The last character in {string⎇ can be
			removed by typing {del⎇.

			While you are in the search mode, EMACS will
			remind you of what you are searching for, by
			displaying

				I-SEARCH: {string⎇

			in the lower-left corner of the screen.

			If there are no occurrences of {string⎇ to the
			right of the pointer, EMACS responds with the
			message

				FAILING I-SEARCH: {string⎇

			and does not move the pointer. At this point,
			typing ↑G will remove characters from the right
			end of {string⎇ until there is an occurrence of
			string in the buffer.

			Once a successful search has been completed,
			typing {esc⎇ will cause EMACS to leave the
			search mode, while ↑G will cause EMACS to
			return the pointer to its original location
			and quit the search mode. Typing ↑S will move
			the pointer to the next occurrence of {string⎇,
			and ↑R will change the forward search to a
			reverse search (see below). Typing any other
			EMACS command will cause EMACS to leave the
			search mode and execute the command.

			If {string⎇ is empty and you type ↑S, the
			string used in the last search becomes the new
			string. (If this is the first search, EMACS
			will not do anything.) When you leave a search,
			EMACS remembers {string⎇.

		↑R	This command is similar to ↑S, except that it
			performs a reverse search. The pointer is moved
			back to the left of the first occurrence of
			{string⎇.

			When in either search mode, you may switch to
			the other by typing its command (either ↑R or
			↑S).

INSERTING	{char-	Any ordinary letter, number or punctuation mark
AND DELETING	acter⎇	is inserted to the left of the pointer.
TEXT			Everything to the right of the new character is
			shifted to the right to accommodate the new
			character. The pointer is moved to the right of
			the new character. For example, to insert an
			"m" into the word "terinal", you must move the
			pointer until the cursor is at the "i",
			then type "m". The buffer will now contain
			"terminal" and the cursor will still point to
			"i", although it is now one character to the
			right of its original position.

		↑D	The character to the right of the pointer, i.e., the
			character above the cursor, is deleted from the
			buffer. Everything in the same line to the right of
			the deleted character is shifted to the left. The
			cursor remains at the same spot, although it now
			points to the character to the right of the deleted
			character.

		{esc⎇D	Like ↑D except deletes a word instead of a character.
			The word is saved on the kill ring (see ↑Y).

		↑Z↑D	Like ↑D except deletes an s-expression instead of
			a character. The s-expression is saved on the kill
			ring (see ↑Y).

		↑Z↑K	Like ↑K except kills an s-expression instead of a line.

		{del⎇	This is identical to ↑D, except that the
			character to the left of the pointer, i.e., left of
			the cursor, is deleted. If the cursor is at the
			beginning of the line, the {cr⎇ of the previous line
			is deleted, causing the pointer's line to be added to
			the end of the previous line.

		{esc⎇{del⎇ Like {del⎇ but deletes a word. The word is saved
			on the kill ring. (see ↑Y)

		↑Z{del⎇ Like {del⎇ but deletes an s-expression. The 
			s-expression is saved on the kill ring. (see ↑Y)

		↑K	This command "kills" (deletes) everything
			between the pointer and the first {cr⎇
			(exclusively) to the right of the pointer. If
			the first character to the right of the pointer
			is a {cr⎇, just that {cr⎇ is killed.

		↑@	This is used in conjunction with ↑W (see
			below). This command marks the pointer's
			current location in the buffer.

		↑W	This command kills everything, including
			{cr⎇'s, between the pointer and the spot marked
			by the ↑@.

		↑X↑X	This command marks the current location and moves the
			cursor to the last location marked.  This allows you to
			check the region to be killed with a ↑W command.

		↑Y	This command "yanks" (inserts) the last thing
			killed (with a ↑K, ↑W, etc) to the right
                        of the pointer. The pointer is moved to the
			right of the inserted string. This command, in
			conjunction with commands like ↑K is useful for 
			moving blocks of text around the buffer by 
			killing a part of the text, moving the pointer, 
			then yanking the text.

		↑Q	The character immediately following the ↑Q is
			inserted, regardless of what it is. For
			example, ↑Q↑L inserts ↑L into the text.
			Although the ↑L is printed as two characters,
			it is actually only one.

		↑T	If there are no characters on the line to the right of
			the pointer, transpose the last two characters typed. 
			Otherwise, interchange the characters on each side of
			the pointer.

CHANGING	{esc⎇C	Capitalizes the first character of the word to
CASE			the right of the pointer and lowercasifies the
			rest of the word. Leaves the pointer after the
			word.

		{esc⎇U	Capitalizes the word to the right of the pointer.
			Leaves the pointer after the word.

		{esc⎇L	Lowercasifies the word to the right of the pointer.


SCHEME		{esc⎇O	Transfers the entire program file back to SCHEME.
COMMANDS

		↑Z Y	Transfers the current DEFINE back to SCHEME.  Assuming
			the cursor is positioned within some procedure
			definition, ↑Z Y will return to SCHEME and load in the
			definition.  The current DEFINE is taken to be the
			smallest SCHEME expression which containing the
			cursor and is preceeded by a carriage-return.  This
			usually means the DEFINE the cursor is inside of
			unless the "(DEFINE .." is not on the left margin
			or is at the very start of the file.

		{esc⎇Z	Copies the current DEFINE into a special file which will
			be loaded into SCHEME when you exit EMACS and return to
			SCHEME via ↑X Z.  The "current" DEFINE is the DEFINE
			containing the cursor.  The cursor moves to the start
			of this DEFINE after it has been copied.  Used when
			several DEFINEs are to loaded into SCHEME, but the
			entire program file should not be loaded.

		↑X Z	(Type ↑X, then type Z.  Not to be confused with ↑X↑Z).
			Saves the program file on disk, returns to SCHEME, and
			loads the special file of DEFINEs which was created
			by {esc⎇Z or {esc⎇O. This is the prefered command for
                        leaving EMACS and returning to SCHEME.


SPECIAL		↑U	This command allows you to tell EMACS to
COMMANDS		perform a command a given number of times.
			The format is

				↑U{number⎇{command⎇

			EMACS will perform the command {command⎇
			{number⎇ times. For example, ↑U5↑F will move
			the pointer forward five characters. If no
			number is given, a default value of 4 is given.
			A ↑U-modified command is itself a command, so
			↑U can be used on itself multiplicatively.
			For example, all the following move the pointer
			forward 64 times:

				↑U64↑F
				↑U8↑U8↑F
				↑U↑U16↑F
				↑U↑U↑U↑F

		{esc⎇{digit⎇ When followed by a number, {esc⎇ will have the
			same result as ↑U. However, it can't be used on
			itself (like ↑U8↑U8↑F), and it doesn't assign a
			default number if no number is given. 

		{esc⎇X	This reads an extended command name terminated by a
			return (see sec. 2.2.4).



2.2.2 BUFFER STORAGE COMMANDS

	After invoking EMACS from EXEC (see sec. 1.3) you may begin inserting
text by simply typing it. However, if you want to modify an existing file, you
must load the file into the buffer. To do this, type

		↑X↑V {filename⎇{cr⎇

You may use the completion and editing conventions of the EXEC to specify the
filename. 

	The bottom of the screen should display some information, including the
word "Main" followed by your filename. This filename is now the default
filename and remains so until a new file is read. If you now type ↑X↑V with no
filename, EMACS will use the default filename.

	The command ↑X↑S will save the buffer into the default file IF the
buffer has been changed since being read. If the buffer has not been changed,
↑X↑S will not perform the command. This command follows the rules for saving
files described in sec. 1.4 and 1.5. For example, if you type

		↑X↑V program.scm{cr⎇

and the current generation number is 5, then program.scm.5 will be read into
the buffer. If the buffer is then changed, typing ↑X↑S will transfer the buffer
to program.scm.6.

	The command

		↑X↑W {different filename⎇{cr⎇

will write the buffer onto {different filename⎇. This command also follows the
rules for saving files.

	Neither ↑X↑W nor ↑X↑S erase the buffer.


2.2.3 OTHER GLOBAL COMMANDS

	The following commands do not depend on the location of the pointer:


     Command	Description

	↑C	Suspend EMACS and return to SCHEME. If EMACS is executing
		a command, two ↑C's are necessary.  In most circumstances
		you will want to use ↑XZ to return to SCHEME, though.



	↑G	Aborts the current command.  Useful if you type ↑Z or {esc⎇ and
		change your mind.

	↑L	Clear the screen and redisplay the buffer.

	{esc⎇?	Describe the command immediately following the question
		mark. For example, {esc⎇?↑D describes the delete
		command. The description is displayed on the screen,
		but the buffer is unchanged. The next character typed
		will remove the description and redisplay the buffer.
		This character will be treated as a command to be
		executed by EMACS, so if you want to redisplay the
		buffer without executing an unwanted command, type ↑L
		after you've read the description that was displayed.

	↑←	The Help character.  Provides general documentation as well as
		the last 60 characters you typed.  Provides specialized
		information during the execution of some commands (e.g., Query 
		Replace in the next section and ↑S).  The Help character is
		↑? on the VT100 terminals.


2.2.4 EXTENDED COMMANDS

	Only a finite number of commands can be acessed with one or two
character command invocations.  To allow an infinite number of commands
to be used, EMACS provides "named" commands where you type a descriptive name
of the command you want to execute.

	To type an extended command, type "{esc⎇X".  This will echo on the line
below the modeline as "M-X".  Then type the name of the command you want to
execute.  You can type ?, {esc⎇, and {space⎇ to help you complete the command.
Typing ? at any point will list the commands that match the text you have typed
so far.  For example, {esc⎇X? will list about 350 extended commands available
in "bare" EMACS.  Typing {esc⎇ will attempt to fully or partially complete the
text you have typed so far.  If some amount of completion cannot be
accomplished (because either the text is ambiguous or does not match any
command), nothing will happen and the terminal will "beep."  Typing {space⎇
will attempt to complete the word you are typing.  If the word is recognized as
being valid when you type {esc⎇ or {space⎇, the initial letter will be
capitalized.

	All M-X commands should be terminated by {cr⎇.  The following list
describes the more useful M-X commands: 

M-X replace{esc⎇{string 1⎇{esc⎇{string 2⎇{esc⎇

	replace all occurrences of {string 1⎇ completely to the right
	of the pointer with {string 2⎇.

M-X query replace{esc⎇{string 1⎇{esc⎇{string 2⎇{esc⎇

	move pointer to the right of the first occurrence of {string 1⎇
	and wait for a response:

	Response 	Result

	{space⎇		Replace this occurrence of {string 1⎇ with
			{string 2⎇ and move to the next occurrence
			of {string 1⎇.

	{del⎇		Move to the next occurrence without replacing
			this one.

	{period⎇	Replace this occurrence and escape the M-X
			command.

	{esc⎇		Escape the M-X command without replacing this
			occurrence.

	!		Replace all remaining occurrences without
			asking.

	All replacements follow the same rules used by replace for
	upper- or lower-case letters. For a more complete list of responses,
	type the help character after you enter query replace.  M-X q{esc⎇
	will also get you the query replace option and involves less typing.

M-X describe{esc⎇{command name⎇

	describe {command name⎇ (e.g., M-X describe{esc⎇query replace),
	much like {esc⎇?, but for M-X commands.

M-X occur{esc⎇{string⎇

	list all lines containing {string⎇.

M-X apropos{esc⎇{string⎇

	list and briefly describe all commands (M-X and others) whose
	names contain {string⎇.

M-X info

	Examine a vast repository of documentation.  Same as EXEC's XINFO
	program.

M-X scheme mode

	change the EMACS mode from fundamental to SCHEME (see sec. 2.3).

2.3 SCHEME MODE

	EMACS has several features which make SCHEME editing easier.
Most of these features have been borrowed from LISP mode, which was
written for MACLISP. The ↑Z↑A and ↑Z↑E commands (see sec. 2.2.1) 
enable you to scan through DEFINEs quickly.  Another feature involves
the closing of delimiters. When you type a closing delimiter (right 
parenthesis, bracket or brace), EMACS will search back from the pointer 
until it finds the corresponding opening (left) delimiter. If the opening
delimiter is on the screen at the time the closing delimiter is typed,
the cursor will momentarily point to the opening delimiter, although
the pointer is unchanged. This allows you to see whether or not you
have the right arrangement of parentheses in a SCHEME procedure. Note:
this feature does not distinguish between parentheses, brackets or
braces.  If the opening delimiter is off the screen you can find it by
using ↑Z↑B or by asking a TA how to enable off-screen matching.

	When you invoke EMACS, the bottom of the screen will display a
message like

		EMACS (Scheme)

This "modeline" shows that EMACS is in the SCHEME mode. If you ever find
that you are in a different mode, you can change this to the SCHEME mode
by typing

		M-X scheme mode

(see sec. 2.2.4). Now the screen will read

		EMACS (Scheme)


	When in the SCHEME mode, you can use the tab key to invoke a SCHEME
pretty-printing procedure. The pretty-printing routine will reposition the
current line in accordance to certain rules for properly indenting SCHEME
programs. For example, if the buffer contains

		(define (fact n)
		(cond ((zero? n) 1)
		(else (* n (fact (-1+ n))))))

and the pointer is in the second line, typing {tab⎇ will change the buffer to
this:

		(define (fact n)
		  (cond ((zero? n) 1)
			(else (* n (fact (-1+ n))))))

For information about the rules of pretty-printing, see MACLISP documentation.

3. INTRODUCTION TO THE SCHEME SYSTEM

	The LISP which is to be used by 6.001 is called SCHEME.  The
6.001 course notes provide an introduction to the SCHEME language.
This chapter describes how to use SCHEME as it is implemented on the
EECS computer system.  It explains how to enter SCHEME, evaluate
expressions, create and edit programs, test programs, and obtain
printed output.  Following this section is the SCHEME reference
manual, where the special forms and procedures are individually
described.


3.1 INVOKING SCHEME

	To enter SCHEME, just type SCHEME{cr⎇ to the monitor. This
will enter SCHEME.  Once you are in SCHEME, type any symbolic
expression (s-expression).  It will be evaluated as soon as you're
done typing its closing parenthesis and its value will be displayed on
the screen for you to see. To evaluate a variable, you will have to
type a {space⎇ after its name.  This process, in which SCHEME prompts
for input, evaluates the expression entered, and prints the result, is
called a read-eval-print loop.  To exit SCHEME temporarily, type
(quit).  Example (note: upper and lower case are not distinguished):

	@SCHEME
	[Keeping]

	[SCHEME.290 in MacLISP.2117]

	==> (define a (+ 3 4))
	A

	==> a{space⎇
	7

	==> (quit)
	@

3.2 USING PROGRAM FILES


3.2.1 CREATING AND EDITING FILES

	The EDIT procedure provides a link between SCHEME and EMACS.
It is in EMACS that program files will be created and edited.  Below
is a sample session with the SCHEME system which illustrates the use
of the EDIT procedure.  The actual editing is not shown, but is
described by ";;;" comments.  This session proceeds as follows: two
procedure definitions are typed in EMACS: SQ, which computes the
square of a number, and COTAN, the co-tangent function.  These
definitions are then loaded into SCHEME using the {esc⎇O command.
Unfortunately, the name of the sine function was inadvertently typed
as "sine" in the COTAN definition (the proper name is "sin"), so an
error occurs while computing the co-tangent of pi/2.  The (edit)
command returns to EMACS and the mistake is corrected.  Then the new
COTAN definition is transmitted back to SCHEME using the ↑Z Y command.
Finally, the COTAN procedure performs correctly on pi/2.
        Notice that when we return from EMACS to SCHEME, the working
buffer in EMACS is automatically saved as another generation of the
file associated with that buffer.  If no file has been associated with
that buffer, EMACS will prompt the user to supply a file name in which
to save the buffer.  This feature ensures that your work is saved.

	@scheme
	[Keeping]

	[Scheme.315 in MacLISP.2118]
	
	==> (edit)
	(=> EMACS)
	
		;;; Type in the following DEFINEs:
	
	(define (sq x) (* x x))
	
	(define (cotan x) (/ (cos x) (sine x)))

		;;; Enter the following command:

	{esc⎇O		;;; Transmit the entire buffer to SCHEME. 
                        ;;; The buffer is first saved by EMACS.
	
	Returning from Editor
	SQ
        COTAN 
        (SCHEME <=)

	
	==> (cotan 1.570796327)
	Error! Unbound variable referenced SINE Level: 2
	
	Error-> ↑G
	Quit! Level: 1
	
	==> (edit)
	(=> EMACS)
	   .
	   .	;;; Change SINE to SIN inside the COTAN
	   .	;;;    definition.
	   .
		;;; Enter the following command to transmit the cotan
		;;; 	define back to SCHEME.  The buffer will be
		;;;	automatically saved by EMACS.
	  ↑ZY	
	
	Returning from Editor
	COTAN 
	(SCHEME <=)

	==> (cotan 1.570796327)
	0

	==> (quit)
	@


3.2.2 LOADING FILES

	If you already have a program file, you can load it into
SCHEME without using the EDIT procedure and going to EMACS; the LOAD
procedure can load SCHEME code from a disk file.  The command is

		(LOAD {filename⎇)

where {filename⎇ is a symbolic expression and will be evaluated.  To
load a known file (rather than the value of a variable), use "'s
around the name.  For example, if you want to load FOO.SCM from the
<LS.SOURCE> directory, you can say:

		(LOAD "<LS.SOURCE>FOO.SCM")

Load will evaluate each expression in the file FOO.SCM.  Most likely,
the files that you will be loading will consist of procedure
definitions exclusively.  Load accepts an optional second argument
which functions as a print flag and can be used to echo these
procedure definitions as they are loaded.  If this argument is
non-NIL, the value of each expression loaded will be displayed on your
console.  Conveniently, the value of a procedure definition is a list
of the procedure's name and its formal parameters.  Hence, supplying a
non-NIL print flag will cause the procedure names to be echoed.  By
default, this flag is NIL.  Incidentally, you will be loading many
files from the <LS.SOURCE> directory during the course of the term.
Of course, if you are loading a file from your own directory, you
needn't include the <{directory name⎇> in the file specification.
Better yet, if {name2⎇, the extension, is "SCM", you can omit it from
the file specification, leaving only {name1⎇, which can be
single-quoted since there are no periods in the file spec. now.

3.3 GETTING HARDCOPY

	If you are on a printing terminal, this section will probably
be of little value to you.  If you're on a video terminal, however,
you may find it nice to know that when your program is running you can
create hardcopy (printed output) on the line printer.

	(PHOTO {filename⎇)

	The procedure PHOTO will save all subsequent output in
{filename⎇.  The procedure TOFU closes the shutter.  You may then use
TOPS-20's PRINT command to print the photo of your session on the
6.001 line-printer.  For example,

	==> (photo "foo.log")

	==> (+ 3 4)
	7

	==> (tofu)

	==> (quit)
	@print foo.log

will produce an output listing that looks like:


	==> (+ 3 4)
	7

	==> (tofu)


	The 6.001 line printer is located in the Course VI terminal
room on the third floor of building 38.  The output will be preceded
by a heading, in large letters, naming the person who requested the
it.

3.4 DEBUGGING

	It will become apparent to you many times during a program's
evolution that the program is not entirely right.  Instead of blaming
the program for these faults, strange creatures called bugs are
blamed.  This way, the programmer remains free of guilt.  Errors and
incorrect results are sure signs that bugs lurk inside a program, for
the bugs cause the aberrant behavior.

	Debugging usually depends on empirical testing, thus it can
serve to re-enforce the programmer's belief in the correctness of his
program, and it can aid in correction of a program which is not
behaving as expected, but it cannot PROVE the program's correctness --
if the program succeeds during debugging, there may be some
yet-to-be-uncovered bug lurking within waiting to show itself in some
later run.  The best protection against program bugs is a program that
is well thought out and clearly set down in code.

	SCHEME provides several features to aid in debugging programs.
Among these are the ability to TRACE the execution of a procedure, the
ability to examine the current environment, and the ability to set
breakpoints.  From a breakpoint, the user can examine the recent
process history of his program.

	Sometimes bugs are detected by the occurrence of an error
while the program was running.  When SCHEME encounters an error
condition, execution is abruptly halted, the user is notified, and a
breakpoint mode is entered, as demonstrated below.

        ==> (+ 1 'a)
	NO-ENVIRONMENT-SAVED
        Error! NON-NUMERIC VALUE A ([PRIMITIVE +] 1 A) Level: 2
   
        Error-> ←

The error message -- a concise description of the error, often
containing the name of the code which signalled the error -- is
displayed.  While the program is suspended, the user can try to locate
where the error occurred, i.e., what expressions were being executed
at the time of the error.  The environment and process history
examiners, WHERE and DEBUG, respectively, can help here.  Of course,
much can be determined about the state of the system at time of the
error by simply examining the values of variables at the breakpoint --
to evaluate a variable, simply type its name!

	The program may run without error, but the result produced may
be preposterous -- another indication of bugs.  For instance,

	==> (prime? 7)
	NIL

In this situation, SCHEME offers no clue as to the location of the bug
-- you're on your own.  You might produce a theory about the cause of
the deviant behavior and then test it using the        TRACE
facilities.  You can also insert checks and traces in your program
with the text editor.

	Debugging, like programming, is an acquired skill and an art.
The tools available to you are described in the sections below.  Use
them creatively.  The undergraduate assistants stationed in the
EECS terminal room are competent debuggers and understand SCHEME's
debugging facilities.  Feel free to ask them for help.


3.4.1 BREAKPOINTS

	As mentioned above, a breakpoint is entered whenever an error
is signalled.  This error may have been signalled internally by
SCHEME, or it may have been signalled by an ERROR statement that the
user inserted in the program himself.  Breakpoints of a slightly
different flavor can be entered via the BKPT procedure or by simply
typing a ↑B from the terminal.

	The SCHEME breakpoint facility allows you to pause execution
of a program "in mid-stream," whereupon you can examine and modify the
values of local variables, among other things.  When you pause
execution and enter a breakpoint, SCHEME runs a read-eval-print loop
just as it normally does -- you type expressions and the interpreter
evaluates them and prints their value.  The difference is that the
environment in which these expressions are evaluated is not the global
environment, but rather the environment from which the breakpoint
was entered.

	Breakpoints can be entered in the following ways:

  * Typing ↑B on the terminal.

  * Executing a procedure which had a breakpoint installed via one of
    the commands BREAK, BREAK-ENTRY, or BREAK-EXIT.

  * Executing the procedure BKPT.

  * Encountering an error (eg, (+ 'a 'b) will surely give such an error.)

Here's a simple scenario which demonstrates how breakpoints can be used:

Suppose you modify the familiar recursive FACT procedure above to
produce the following new procedure:
	
	(define (newfact n)
	   (cond ((zero? n) 1)
	         (else (* n (newfact (- n 2))))))

The idea is to compute the product of all the even (resp. odd) numbers
up to some even (resp. odd) number n.  You try (newfact 6) which gives
48 = 6*4*2 as expected.  But when you try (newfact 7) you get no
reply.  So you type ↑B and SCHEME responds with

Bkpt-> 

The "BKPT" message says that the breakpoint was caused by user
intervention, e.g., typing ↑B, rather than by an error (in which case
SCHEME would have typed "ERROR").  The number preceding "BKPT" tells
how many "break levels" you are away from the main read-eval-print
loop execution -- if you entered another breakpoint from within this
one, that would be Level 2, and so on.  The top-level read-eval-print
is at level 0.

Now that you are within the break, you can examine the value of the
local variable n:

Bkpt-> n
-141

Seeing that n is negative should give you a good clue to uncovering
the bug.

	To continue from a breakpoint, type "{esc⎇P{space⎇", which
prints as "$P".  The interpreter will continue the execution of the
procedure from which the breakpoint was called, but, if the breakpoint
was forced by ↑X (e.g. ↑B↑X), the continuation may be faulty because
SCHEME was not allowed the chance to cleanup before breaking.
Alternatively, you can type ↑G, which halts execution and returns to
the top-level read-eval-print loop, or you can type ↑U which halts
execution and returns to the preceding read-eval-print loop.  ↑X halts
execution locally and resumes the current read-eval-print loop.

Breakpoints entered because of an error are special -- they act as
error sinks.  To avoid confusing you with more than one error at a
time, errors encountered in evaluating things typed at the error
breakpoint will not sprout new breaklevels.  A new error's message is
printed, as usual, but execution resumes at the first error's break
loop.  This way, all attention can be focused on the original error.
Although error recovery is often possible, you probably won't want to
fool with it.  When an error occurs, find out all you can about it
using DEBUG and WHERE.  Then type ↑G to return to top-level, where
the error can be permanently fixed.

You may find it helpful to know that different prompts are used for
the different modes.  The top-level prompt is "==>", the break prompt
is "Bkpt->", and the error prompt is "Error->".  

3.4.2 USEFUL CONTROL-CHARACTERS

	Certain control characters can be typed in SCHEME during the
execution of any operation to achieve useful effects.  Most of these
manipulate break levels.

	↑B -- Enters a Breakpoint (described later in this section).

	↑C -- Returns to the monitor.

	↑G -- Halts execution at all levels. Returns to toplevel 
	      read-eval-print loop.

	↑L -- Clears the screen. If any input has been typed, it will be	
	      redisplayed.

	↑P -- Abort output.  The current print procedure is aborted
	      and execution continues.

	↑R -- Retype the current input expression (doesn't clear screen).

	↑U -- Halts execution locally. Returns to the previous (next
	      innermost) breaklevel if it exists, else returns to toplevel.

	↑X -- Halts execution locally. Returns to the innermost breaklevel
	      if any exist, or to toplevel if none exist.


	After acknowledging a ↑B, SCHEME enters a breakpoint at the
next convenient time.  This may not be convenient for the user,
however, so an immediate breakpoint facility is provided.  If ↑B
doesn't seem to have any effect, and an immediate breakpoint is
desired, then follow it with a ↑X to force it through.  Thus, ↑B↑X
enters an immediate breakpoint.  Forcing a breakpoint in this manner
may, however, prevent you from continuing your program.  Proceeding
from breakpoints is explained in the next section.



3.4  ENTERING THE DEBUGGING MODE

          A breakloop will only allow you to examine local variables and 
evaluate expressions at the breakpoint. The SCHEME debugger may help you locate
the piece of code from which the error was signalled. A SCHEME expression
is evaluated in a certain environment -- an environment being simply a 
function which maps variables to their values. In SCHEME, this environment
consists of a sequence of frames, each frame being constructed by the 
application of a procedure to its arguments. The arguments are the values
of the parameter variables of the procedure. The frame is constructed, in
the lexical environment of the definition of the procedure. The arguments and
the procedure expression are evaluated in that environment.

One of SCHEME's design principles is never to save anything that isn't
needed.  This policy is responsible for order of magnitude space
savings in the execution of certain procedures and for the ability to
execute tail-recursive procedures as iterative processes.
Environments are only needed to look up the values of variables, thus
we can only depend on SCHEME to save a valid environment when it is
accessing variables.  In other words, the "Unbound Variable" errors
are the only errors in which the environment of the error is saved.
But, even if there is no environment of the error saved, a finite
history of the evaluation process is always stored.  This can be
examined using the history examiner.

    The history examiner allows the user to examine the history of
execution of an expression after it has been executed. The environment
of any procedure application may then be examined and the interrupted
process may be proceeded from any of the displayed nodes of
evaluation.

    The environment examiner, the other feature of the debugging
system, allows the user to examine variable bindings in an environment
and change these bindings by entering a read-eval-print loop in that
environment.

    When you call the debug procedure from within a SCHEME breakpoint
you enter one of the two modes of the history package, the LAZY-MODE
or the NORMAL-MODE, depending on which was last called. If the debug
procedure is called for the first time, the debugger supplies the
LAZY-MODE as the default.

    In the LAZY-MODE, a read-execute-loop is entered, which accepts
single character commands which allow you to enter different history
levels, move backwards and forwards in the same history level and
examine the procedures and variables there.  The prompt is
Lazy-debug-->.

      The debugger is demonstrated below.

      ==> (load 'fact)

      T

      ==> (pp fact)
      [PROCEDURE (FACT N) (IF (ZERO? N) L (* N (FACT (-1+ N))))]

      ==> (fact 3)
      Error! Unbound variable referenced L Level: 2

      Error-> (debug)

      Subproblem-level: 0  Reduction number: 0
      Expression L 
      Within Procedure [PROCEDURE FACT] applied to (0)

      Subproblem-level: 0  Reduction number: 1
      Expression (IF (ZERO? N) L (* N (FACT (-1+ N))))
      Within Procedure [PROCEDURE FACT] applied to (0)

      Subproblem-level: 0  Reduction number: 2
      Expression (FACT (-1+ N))
      Within Procedure [PROCEDURE FACT] applied to (1)

      Subproblem-level: 1  Reduction number: 0
      Expression (* N (FACT (-1+ N)))
      Within Procedure [PROCEDURE FACT] applied to (1)

      Subproblem-level: 1  Reduction number: 1
      Expression (IF (ZERO? N) L (* N (FACT (-1+ N))))
      Within Procedure [PROCEDURE FACT] applied to (1)

      Subproblem-level: 1  Reduction number: 2
      Expression (FACT (-1+ N))
      Within Procedure [PROCEDURE FACT] applied to (2)

      Subproblem-level: 2  Reduction number: 0
      Expression (* N (FACT (-1+ N)))
      Within Procedure [PROCEDURE FACT] applied to (2)

      Subproblem-level: 2  Reduction number: 1
      Expression (IF (ZERO? N) L (* N (FACT (-1+ N))))
      Within Procedure [PROCEDURE FACT] applied to (2)

      Subproblem-level: 2  Reduction number: 2
      Expression (FACT (-1+ N))
      Within Procedure [PROCEDURE FACT] applied to (3)

      Subproblem-level: 3  Reduction number: 0
      Expression (* N (FACT (-1+ N)))
      Within Procedure [PROCEDURE FACT] applied to (3)

      Subproblem-level: 3  Reduction number: 1
      Expression (IF (ZERO? N) L (* N (FACT (-1+ N))))
      Within Procedure [PROCEDURE FACT] applied to (3)

      Subproblem-level: 3  Reduction number: 2
      Expression (FACT 3)
      Within Procedure [LAMBDA PROCEDURE 200352]
        APPLIED TO ([ENVIRONMENT 195068])


      Lazy-debug--> w                               ; invoking the environment
						    ; examiner

      Where--> p				    ; the parent frame of the
						    ; current one
      ((*THE-ENVIRONMENT* [ENVIRONMENT 190568])
       (FACT [PROCEDURE FACT])
   
      Where--> e				    ; creates a read-eval-print
						    ; loop in the current frame
      You are now in desired level Level: 3	    ; to change its bindings


      Eval-in-env--> (define l 1)                   
      L
    
      Eval-in-env--> (fact 3)
      6

      Eval-in-env--> π
    
      Quit! Level: 1
   
      ==> (fact 4)                                  ; L is now bound to 1
      24

     
      The above factorial program has a simple typo--the letter "L" is
used instead of the number "1" in the second line of code -- resulting
in an "Unbound variable" error. The debugger indicates that the error
was encountered when FACT was called with 0 as its argument.  Once the
user spots the mistake, he can rebind L to 1 in the desired
environment and continue with his computation.  In subsequent calls to
the factorial program, there will be no error.

      Before going any further, it would be necessary to explain the
subproblem levels and reduction numbers that are displayed in history.
Referring to the example of the factorial program above, you will
notice that all the reductions at the same subproblem level represent
expressions which have the same value.  An expression with a lower
reduction number is just a simplification of the expression with a
higher reduction number.  On the other hand, an expression with a
lower subproblem level is a part of an expression with a higher
subproblem level.  The value of the former is necessary for the
evaluation of the latter.  Therefore, in the evaluation of a compound
expression, we break it into subproblems and go through many
reductions of each subproblem.  Each of these levels of evaluation are
displayed in history to facilitate debugging.


      ==> (load 'sqroot)
      T 
      ==> (pp sqroot)
      [PROCEDURE (SQROOT X)
          (DEFINE (SQRT-ITER ANS)
              (IF (GOOD-ENUF? ANS) ANS (SQRT-ITER (AVERAGE (/ X ANS) ANS))))
          (DEFINE (GOOD-ENUF? ANS) (< (ABS (- (* ANS ASN) X)) .0001))
          (DEFINE (AVERAGE X Y) (/ (+ X Y) 2))  
          (SQRT-ITER 1)]

      ==> (sqroot 3)
      Error! Unbound variable referenced ASN Level: 2

      Error-> (debug)

      Subproblem level: 0  Reduction number: 0  
      Expression (ERROR *MESSAGE* *IRRITANT*)  
      Within procedure [LAMBDA-PROCEDURE 200352]
        applied to ([ENVIRONMENT 194556])
         
      
      Subproblem level: 1  Reduction number: 0  
      Expression ASN  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  
      
      Subproblem level: 2  Reduction number: 0  
      Expression (* ANS ASN)  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  
      
      Subproblem level: 3  Reduction number: 0  
      Expression (- (* ANS ASN) X)  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  
      
      Subproblem level: 4  Reduction number: 0  
      Expression (ABS (- (* ANS ASN) X))  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  
      
      Subproblem level: 5  Reduction number: 0  
      Expression (< (ABS (- (* ANS ASN) X)) 1.0E-4)  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  
      
      Subproblem level: 5  Reduction number: 1  
      Expression (GOOD-ENUF? ANS)  
      Within procedure [PROCEDURE SQRT-ITER] applied to (1)  
      
      Subproblem level: 6  Reduction number: 0  
      Expression (IF (GOOD-ENUF? ANS) ANS (SQRT-ITER (AVERAGE (/ X ANS) ANS)))  
      Within procedure [PROCEDURE SQRT-ITER] applied to (1)  
      
      Subproblem level: 6  Reduction number: 1  
      Expression (SQRT-ITER 1)  
      Within procedure [PROCEDURE SQROOT] applied to (3)  
      
      Subproblem level: 6  Reduction number: 2  
      Expression
          (SEQUENCE
              (DEFINE (SQRT-ITER ANS)
                  (IF (GOOD-ENUF? ANS) ANS (SQRT-ITER (AVERAGE (/ X ANS) ANS))))
              (DEFINE (GOOD-ENUF? ANS) (< (ABS (- (* ANS ASN) X)) 1.0E-4))
              (DEFINE (AVERAGE X Y) (/ (+ X Y) 2))
              (SQRT-ITER 1))
         
      Within procedure [PROCEDURE SQROOT] applied to (3)  
      
      Subproblem level: 6  Reduction number: 3  
      Expression (SQROOT 3)  
      Within procedure [LAMBDA-PROCEDURE 200352]
        applied to ([ENVIRONMENT 194556])
         
      Lazy-debug--> d
      
      Subproblem level: 1  Reduction number: 0  
      Expression ASN  
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)  

      Lazy-debug--> d					   ;going down to the
							   ;previous subproblem
      Subproblem Level : 2   Reduction number : 0          ;level
      Expression (* ANS ASN)
      Within procedure [PROCEDURE GOOD-ENUF?] applied to (1)

      Lazy-debug--> p

      [PROCEDURE (GOOD-ENUF? ANS) (< (ABS (- (* ANS ASN) X)) .0001))

      Lazy-debug--> π

      Above is a squareroot program which is appropriately divided
into sub-procedures. It harbors a bug. The debugger was called to reveal
that the unbound variable ASN is in the expression (* ANS ASN) which is
part of the definition of GOOD-ENUF?. The bug in GOOD-ENUF?, which is
itself a sub-procedure of SQROOT, can be fixed easily by substituting
ASN with ANS.

      ==> (mapcar (lambda (x) (+ x y)) '(1 2 3))
      Error! Unbound variable referenced Y Level: 2
      
      Error-> (debug)
      
      Subproblem level: 0  Reduction number: 0  
      Expression (ERROR *MESSAGE* *IRRITANT*)  
      Within procedure [LAMBDA-PROCEDURE 200352]
        applied to ([ENVIRONMENT 194556])
         
      
      Subproblem level: 1  Reduction number: 0  
      Expression Y  
      Within procedure [LAMBDA-PROCEDURE 175492] applied to (3)  
      
      Subproblem level: 2  Reduction number: 0  
      Expression (+ X Y)  
      Within procedure [LAMBDA-PROCEDURE 175492] applied to (3)  
      
      Subproblem level: 2  Reduction number: 1  
      Expression (F (CAR L))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (3))
         
      
      Subproblem level: 3  Reduction number: 0  
      Expression (CONS (F (CAR L)) (MAPCAR F (CDR L)))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (3))
         
      
      Subproblem level: 3  Reduction number: 1  
      Expression (IF (NULL? L) NIL (CONS (F (CAR L)) (MAPCAR F (CDR L))))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (3))
         
      
      Subproblem level: 3  Reduction number: 2  
      Expression (MAPCAR F (CDR L))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (2 3))
         
      
      Subproblem level: 4  Reduction number: 0  
      Expression (CONS (F (CAR L)) (MAPCAR F (CDR L)))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (2 3))
         
      
      Subproblem level: 4  Reduction number: 1  
      Expression (IF (NULL? L) NIL (CONS (F (CAR L)) (MAPCAR F (CDR L))))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (2 3))
         
      
      Subproblem level: 4  Reduction number: 2  
      Expression (MAPCAR F (CDR L))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (1 2 3))
         
      
      Subproblem level: 5  Reduction number: 0  
      Expression (CONS (F (CAR L)) (MAPCAR F (CDR L)))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (1 2 3))
         
      
      Subproblem level: 5  Reduction number: 1  
      Expression (IF (NULL? L) NIL (CONS (F (CAR L)) (MAPCAR F (CDR L))))  
      Within procedure [PROCEDURE MAPCAR]
        applied to ([LAMBDA-PROCEDURE 175492] (1 2 3))
         
      
      Subproblem level: 5  Reduction number: 2  
      Expression (MAPCAR (LAMBDA (X) (+ X Y)) '(1 2 3))  
      Within procedure [LAMBDA-PROCEDURE 200352]
        applied to ([ENVIRONMENT 194556])
         
      
      Lazy-debug--> d					   ;previous subproblem
         
      Subproblem level: 1  Reduction number: 0  
      Expression Y  
      Within procedure [LAMBDA-PROCEDURE 175492] applied to (3)  
							   
      Lazy-debug--> d					   ;previous subproblem

      Subproblem level : 2  Reduction number : 0
      Expression (+ X Y)
      Within procedure [LAMBDA PROCEDURE 183045] applied to (3)

      Lazy-debug--> w				          ;invoking the environment
							  ;examiner

      Where--> h                                        ;displays bindings in
							  ;current environment
      ((X 3))

      Where--> p					  ;parent environment

      ((*THE-ENVIRONMENT* [ENVIRONMENT 299377]))

      Where--> e					  ;create a read-eval-print
							  ;loop to change bindings 
      Eval-in-env--> (define y 2)
      Y
       
      Eval-in-env--> (mapcar (lambda (x) (+ x y)) '(1 2 3))
      (3 4 5)

      Eval-in-env--> π

      Quit! Level: 1

      ==> (mapcar (lambda(x) (+ x y)) '(1 2 3))
      (3 4 5)

      The error was found to be local to the environment created by
      the evaluation of the LAMBDA expression. To fix the bug, Y was
      defined globally to be 2.

        
      You may have noticed from the order of the expressions in the
above example, that the SCHEME implementation is similar to Hebrew in
one respect--the order of evaluation.  A procedure's arguments are
evaluated right to left in SCHEME; Hebrew text is read right to left.
This fact may be helpful in debugging, but your programs should never
depend on the order of evaluation, or any other implementation-
dependent aspects of a language.

        Here is a more complex example showing error recovery:

        ==> (define (a x y zee) (+ x y z))
        A

        ==> (define (b z) (- 10 z))
        B

        ==> (define (c) (b (a 1. 2. 3.)))
        C

        ==> (c)
        Error! Unbound variable referenced Z Level: 2	

        ==> (debug)

	Subproblem level: 0  Reduction number: 0  
	Expression (ERROR *MESSAGE* *IRRITANT*)  
	Within procedure [LAMBDA-PROCEDURE 200352]
	  applied to ([ENVIRONMENT 194556])
   
	
	Subproblem level: 1  Reduction number: 0  
	Expression Z  
	Within procedure [PROCEDURE A] applied to (1 2 3)  

	Subproblem level: 2  Reduction number: 0  
	Expression (+ X Y Z)  
	Within procedure [PROCEDURE A] applied to (1 2 3)  

	Subproblem level: 2  Reduction number: 1  
	Expression (A 1 2 3)  
	Within procedure [PROCEDURE C] applied to NIL  

	Subproblem level: 3  Reduction number: 0  
	Expression (B (A 1 2 3))  
	Within procedure [PROCEDURE C] applied to NIL  

	Subproblem level: 3  Reduction number: 1  
	Expression (C)  
	Within procedure [LAMBDA-PROCEDURE 200352]
	  applied to ([ENVIRONMENT 194556])
   
        Lazy-debug--> d
   
	Subproblem level: 1  Reduction number: 0  
	Expression Z  
	Within procedure [PROCEDURE A] applied to (1 2 3)  

        Lazy-debug--> r                     ; Z is defined to be zee
        Exp to proceed with: -> zee
        Confirm: [T or NIL] -> T

        4

        
        The error occurred because Z was unbound, but since Z is used
in at least two procedures, we need more information to locate the
bug. Calling the debug procedure enters us into the history package,
which tells us that the error is within procedure A.  The command P
prints out the procedure and by examining it, we can see that the name
of its third formal parameter has been spelled incorrectly.  The
command R prompts for a value for the unbound variable Z and resumes
the execution.

The commands available in the debugging system are explained below.

The commands to move between levels and reductions are:

- D (Previous-subproblem in NORMAL-MODE) which moves to the subproblem
	waiting for the value to be returned from the current one
- U (Next-subproblem) moves to the subproblem whose value the current
	one is waiting for
- B (Previous-reduction) which moves to the reduction from which the
	current one came
- F (Next-reduction) which moves to the reduction into which the
	current one was reduced
- G (Go), takes two arguments and moves to the reduction and subproblem
	level specified by them

The commands to access information from history are:

- X (Subexpressions) displays the subexpressions at this level
- S (Reduction) displays the current reduction in short form
- A (All-reductions) displays all the reductions at the current level
- H (All-history) displays all available history

Other useful procedures are:

- W (Debug-where) calls WHERE on the environment of the current 
            reduction, displaying and manipulating it
- P (Print-procedure) prints the current procedure
- V (Eval-in-current-environment) evaluates an expression
- E (Enter) enters a read-eval-print loop in the current environment
- R (Return) binds the expression to the value given as an argument,
           and proceeds with the evaluation in the current environment
- M (Toggle) changes the debug mode
- Q (Exit) exits the debugger
- ? (Help) gives information on the commands

       W is the command which calls (WHERE) and invokes the
environment package which allows the user to examine variable bindings
in an environment, or any of its parent frames and to change these
bindings by entering a read-eval-print loop in the appropriate
environment. It takes single letter commands. WHERE can be called from
the error level with (WHERE). It prompts with Where-->.

       The possible actions are:
 
       E      Creates a read-eval-print loop in the current frame so that its
              bindings can be changed
       S      Finds the frame whose parent frame is the current one and can be
              accessed from the environment originally given to WHERE

       P      Finds the parent frame of the current one
       H      Displays the bindings in the current environment
       A      Displays the bindings of all the frames that can be accessed in 
              the current chain
       Q      Exits the read-execute-print loop
       ?      <Help>, prints help information

	In the NORMAL-MODE, you can implement the same actions, except
that, instead of the commands given, you have to give complete
procedures (those given within brackets) on the terminal.  For
example, the command P in the LAZY-MODE would be equivalent to
Print-Procedure in the NORMAL-MODE.

	While in LAZY-MODE, a read-execute-print loop is entered, in
the NORMAL-MODE, a special READ-EVAL-PRINT loop is entered which has
access to the internal functions and variables of the history
examiner, making them available to the user so that he can write his
own display and manipulation procedures. In this sense, the
NORMAL-MODE is more complete, though the LAZY-MODE is easier to type
and is really more useful.


3.4.4 TRACE and BREAK

	Procedures are provided which allow the user to trace the
execution of a program and set breakpoints in the program.  A
procedure can be traced on entry and/or exit.  In addition, a
breakpoint can be set when the procedure is entered and/or exited.


Example:

	==> (define (fact n)
	        (cond ((zero? n) 1)
	              (else (* n (fact (-1+ n))))))
	FACT 
	==> (trace fact)
	[PROCEDURE FACT]
	
	==> (fact 6)
	[ Entering (FACT 6) ]
	[ Entering (FACT 5) ]
	[ Entering (FACT 4) ]
	[ Entering (FACT 3) ]
	[ Entering (FACT 2) ]
	[ Entering (FACT 1) ]
	[ Entering (FACT 0) ]
	[ 1 <== (FACT 0) ]
	[ 1 <== (FACT 1) ]
	[ 2 <== (FACT 2) ]
	[ 6 <== (FACT 3) ]
	[ 24 <== (FACT 4) ]
	[ 120 <== (FACT 5) ]
	[ 720 <== (FACT 6) ]
	720 
	
	==> (untrace-exit fact)
        ([PROCEDURE FACT])
	
	==> (fact 6)
	[ Entering (FACT 6) ]
	[ Entering (FACT 5) ]
	[ Entering (FACT 4) ]
	[ Entering (FACT 3) ]
	[ Entering (FACT 2) ]
	[ Entering (FACT 1) ]
	[ Entering (FACT 0) ]
	
	720 

	
	==> (untrace fact)
	[PROCEDURE FACT]
	

	==> (break-exit fact)
	[PROCEDURE FACT]
	
	==> (fact 2)
        [ 1 <== (FACT 0) ]
	Bkpt! Exiting *result* <== (*proc* . *args*) [ENVIRONMENT] Level: 2

	Bkpt-> *proc*
	[PROCEDURE FACT]

	Bkpt-> *args*
	(0)

	Bkpt-> *result*
	1

	Bkpt-> (set! *result* -1)
	-1

	Bkpt-> $p

	[ -1 <== (FACT 1) ]
        Bkpt! Exiting *result* <== (*proc* . *args*) [ENVIRONMENT] Level: 2

	Bkpt-> $p

	[ -2 <== (FACT 2) ]
	Bkpt! Exiting *result* <== (*proc* . *args*) [ENVIRONMENT] Level: 2

        Bkpt-> $p
	-2
	
	==>

During the breakpoint inserted by BREAK, the global variables *PROC*,
*ARGS*, and *RESULT* hold the broken procedure, its argument values,
and the computed result (available only during the exit break),
respectively, for examination.  The user may change the value returned
by the procedure by assigning to *RESULT* the value to be returned.
Type $P, {esc⎇P, to proceed from the breakpoint and return *RESULT*.
In the above example, (FACT 0) returned -1 instead of 1.



3.4.7 MOST RECENT INPUT AND OUTPUT LINES

	In SCHEME, the procedures %IN and %OUT return the most
recently read and printed expressions, respectively.  This may be
useful if you forget to assign a variable to the result of some
calculation until after doing the calculation.  This is provided as a
debugging aid for use at the terminal; it should never be used in
programs that you write.  For example:

	==> (+ 2 5)          
	7

	==> (DEFINE SEVEN (%OUT))
	SEVEN

	==> (%IN)
        (DEFINE SEVEN (%OUT))

        ==> SEVEN
	7


3.4.8 PRINT-LEVEL/PRINT-LENGTH

	It is possible to create structures in SCHEME which are
circular and which cannot be printed to completion.  Trying to prh∞t
such a structure may result in an error; a lot of paper will be used
in any event.

	The global variables *PRINT-DEPTH* and *PRINT-BREADTH* are
used to restrain the printer. *PRINT-DEPTH* is the number of nested
levels of a structure which will be printed to completion, while
*PRINT-BREADTH* is the number of top-level elements which will be
printed.  Ellipses ("...")  appear in the ouput where these limits
have been exceeded.  You may set these limits to your liking.

	==> (define a '(a (b c) (d e (f g h) (i (j k) l) m (n o) p)))
	A

	==> a

	(A (B C) (D E (F G H) (I (J K) L) M (N O) P))

	==> (set! *print-depth* 2)
	2

	==> A 
	(A (B C) (D E (# # #) (# # #) M (# #) P))

	==> (set! *print-breadth* 3)
	3


	==> A 
	(A (B C) (D E (# # #) ...))  

	==> (SET-CDR! A A)
	(A A ...)


3.5 THE SCHEME PRETTY-PRINTER

	A Pretty-Printer is a procedure which will take a data object
and try to display it in a nice form which shows up its structure
easily.  SCHEME has a simple, but useful pretty-printer which is
called PP.  It evaluates its argument and displays it on the terminal
in a more useful way than print might.  Since it is slow and can waste
paper, it is not the normal printer.  Example:

	==> (pp fact)

        [PROCEDURE (FACT N) (IF (ZERO? N) 1 (* N (FACT (-1+ N))))]


We have tried to give an overview of the SCHEME system above,
providing examples where most needed.  Many procedures were glossed
over, while the debugging and error system were covered in great
detail.  The next section, organized for quick referrence, documents
most of the procedures which are available in the SCHEME system.